# -*- coding:utf-8 -*-
# title           :
# description     :
# author          :Python超人/三月三提供
# date            :2024-07-25
# link            :https://gitcode.net/pythoncr/
# python_version  :3.9
# ==============================================================================
from 神笔码靓.码靓库.地理.地图数据 import 获取中国地图数据
from 神笔码靓.神笔库 import 神笔绘图板, 作品输出目录, 资源库目录
from 神笔码靓.神笔库.元素库 import 文字元素
from 神笔码靓.神笔库.定义集 import *
from 神笔码靓.神笔库.通用工具集 import *


class 中国地图拼图(神笔绘图板):
    文字调整 = {
        "北京": lambda 字, 位置: 字.平移(2, -3),
        "内蒙古": lambda 字, 位置: 字.字符间距(60).字旋转(25).旋转(-25, 位置.中心点).平移(0, 20).文字("古蒙内"),
        "甘肃": lambda 字, 位置: 字.字符间距(120).水平基线对齐(文字水平基线对齐.起始点对齐).字旋转(-38).旋转(38, 位置.中心点).平移(-95, 10),
        "吉林": lambda 字, 位置: 字.字符间距(8).旋转(-20).字旋转(20).平移(5, 10).文字("林吉"),
        "辽宁": lambda 字, 位置: 字.字符间距(16).旋转(20).字旋转(-20).平移(15, -5),
        "陕西": lambda 字, 位置: 字.字符间距(35).字旋转(-102).旋转(102, 位置.中心点).平移(33, -5),
        "山西": lambda 字, 位置: 字.平移(-5, 12),
        "河南": lambda 字, 位置: 字.字符间距(10).平移(0, 3),
        "河北": lambda 字, 位置: 字.字符间距(48).旋转(-65).字旋转(65).平移(22, -3).文字("北河"),
        "山东": lambda 字, 位置: 字.字符间距(10).旋转(-20).字旋转(20).平移(-6, -1),
        "宁夏": lambda 字, 位置: 字.字符间距(5).旋转(70).字旋转(-70).平移(12, 8),
        "上海": lambda 字, 位置: 字.平移(-3, 6),
        "香港": lambda 字, 位置: 字.平移(5, -5),
        "重庆": lambda 字, 位置: 字.平移(-4, 4),
        "澳门": lambda 字, 位置: 字.平移(-5, -5),
        "黑龙江": lambda 字, 位置: 字.字符间距(15).旋转(30).字旋转(-30).平移(30, 20),
        "广东": lambda 字, 位置: 字.字符间距(20).旋转(-22).字旋转(22).平移(15, -4),
        "广西": lambda 字, 位置: 字.字符间距(10).平移(6, -4),
        "江西": lambda 字, 位置: 字.平移(-3, 0),
        "福建": lambda 字, 位置: 字.平移(-6, 3),
        "浙江": lambda 字, 位置: 字.平移(-8, 5),
        "湖北": lambda 字, 位置: 字.字符间距(5).平移(5, 0),
        "湖南": lambda 字, 位置: 字.字符间距(0).平移(0, 0),
        "安徽": lambda 字, 位置: 字.平移(0, 15),
        "江苏": lambda 字, 位置: 字.字符间距(5).旋转(45).字旋转(-45).平移(8, -2),
        "新疆": lambda 字, 位置: 字.字符间距(80).平移(70, 10),
        "西藏": lambda 字, 位置: 字.字符间距(80).平移(50, 15),
        "青海": lambda 字, 位置: 字.字符间距(40).平移(20, -10),
        "四川": lambda 字, 位置: 字.字符间距(25).旋转(50).字旋转(-50).平移(20, 5),
        "云南": lambda 字, 位置: 字.字符间距(10).平移(-8, 10),
        "贵州": lambda 字, 位置: 字.字符间距(10).平移(6, 10),
        "海南": lambda 字, 位置: 字.平移(-20, -12),
        "台湾": lambda 字, 位置: 字.字符间距(5).字旋转(-112).旋转(112, 位置.中心点).平移(7, -4),

    }

    # 重新生成的颜色映射
    默认区域颜色 = {
        "北京": "#FF3300", "重庆": "#F58B6B", "上海": "#F58B6B", "天津": "#B1DAAA", "内蒙古": "#FFEBB0", "甘肃": "#0A97FC",
        "陕西": "#F45EF1", "河北": "#A0DBFA", "山西": "#A7F864", "辽宁": "#F2C472", "吉林": "#F47C7A", "黑龙江": "#BCEEAE",
        "江苏": "#86D476", "浙江": "#D2D478", "安徽": "#E5F7BC", "福建": "#A5E4E3", "江西": "#DE74E1", "山东": "#F3E691",
        "河南": "#F2C87C", "湖北": "#0A97FC", "湖南": "#8EF1F9", "广东": "#F2C87C", "广西": "#A6ACF9", "海南": "#94FC43",
        "四川": "#93F3FB", "贵州": "#9C8599", "云南": "#FCFFA6", "西藏": "#FF7806", "青海": "#93FB44", "宁夏": "#DDC975",
        "新疆": "#FDD5B2", "台湾": "#EDAEA3", "香港": "#FF3300", "澳门": "#FF3300"
    }

    省会坐标 = {
        "哈尔滨": (670, 151),
        "呼和浩特": (483.8, 237), "沈阳": (631.5, 223), "长春": (655, 186), "石家庄": (518.5, 282, 6),
        "北京": (542, 253), "天津": (552.5, 267), "太原": (493.5, 285), "济南": (551, 304), "郑州": (507.5, 334, -12, 8),
        "西安": (448, 340), "银川": (413.5, 275.2, 5, 20), "兰州": (383.5, 313.5), "西宁": (357.7, 305, -10, 15),
        "南京": (572.5, 374.5, 11, 11), "合肥": (553, 378), "武汉": (515, 396, 0, 1), "上海": (606, 386), "成都": (386, 396),
        "重庆": (418, 411), "杭州": (590, 400, 0, 17), "南昌": (535.5, 423.5), "长沙": (499, 430), "福州": (579, 460, -10),
        "广州": (503, 501), "台北": (607, 476, -3, 12, 5.5), "南宁": (441, 505), "昆明": (370.8, 477.2), "拉萨": (223, 410),
        "乌鲁木齐": (179, 186), "海口": (465, 546, -2, 12, 5.5), "贵阳": (419, 452.6)
    }

    def __init__(self, 作品文件路径: str, 宽=None, 高=None, 区域文字微调=None, 区域颜色=None, 省会文字微调=None):
        super(中国地图拼图, self).__init__(作品文件路径=作品文件路径, 宽=宽, 高=高)
        self.完整地图数据 = 获取中国地图数据(是否高清=是)
        self.地图数据 = {}
        self.区域文字微调 = 区域文字微调
        self.省会文字微调 = 省会文字微调
        if 区域颜色 is None:
            区域颜色 = {}
        self.区域颜色 = 区域颜色
        for 城市 in self.完整地图数据:
            self.地图数据[城市] = self.减少细节数据(城市)

    def 减少细节数据(self, 城市, 精确距离值=2.1):
        坐标数据列表 = self.完整地图数据[城市]
        result = []
        last_point = None
        for i, point in 索引列举(坐标数据列表):
            if len(point) == 3:
                c, x, y = point  # 将坐标数据转换为浮点数
                # if last_point is None or abs(x - last_point[0]) >= 精确距离值 or abs(y - last_point[1]) >= 精确距离值:
                if last_point is None or self.距离((x, y), last_point) >= 精确距离值:
                    result.append((c, x, y))
                    last_point = (x, y)
            else:
                result.append(point)

        return result

    def 距离(self, 点1, 点2):
        x1, y1 = 点1
        x2, y2 = 点2
        distance = math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
        return distance

    # def 减少细节数据_2(self, 坐标数据列表, 精确距离值=2):
    #     result = []
    #     points_fiterred = []
    #     last_point = None
    #     for point in 坐标数据列表:
    #         if len(point) == 3:
    #             c, x, y = point  # 将坐标数据转换为浮点数
    #             # if last_point is None or \
    #             #         abs(x - last_point[0]) >= 精确距离值 or abs(y - last_point[1]) >= 精确距离值:
    #             if last_point is None or self.距离((x, y), last_point) >= 精确距离值:
    #                 # abs(x - last_point[0]) >= 精确距离值 or \
    #                 # abs(y - last_point[1]) >= 精确距离值 or \
    #                 last_point = (x, y)
    #             else:
    #                 points_fiterred.append((c, x, y))
    #
    #     for point in 坐标数据列表:
    #         if len(point) == 3:
    #             c, x, y = point  # 将坐标数据转换为浮点数
    #             if (c, x, y) not in points_fiterred:
    #                 result.append((c, x, y))
    #         else:
    #             result.append(point)
    #
    #     return result

    def 绘制地图(self):
        区域文字信息列表 = self._绘制区域线()
        self.绘制省会()
        self._绘制区域名称(区域文字信息列表)

    def 绘制省会(self):
        for 省会 in self.省会坐标:

            省会坐标 = self.省会坐标[省会]
            x, y, *offset = 省会坐标
            font_size = 7
            if len(offset) == 1:
                offset_x = offset[0]
                offset_y = 0
            elif len(offset) == 2:
                offset_x, offset_y = offset
            elif len(offset) == 3:
                offset_x, offset_y, font_size = offset
            else:
                offset_x, offset_y = 0, 0

            if 省会 == "北京":
                self.画五角星(x=x, y=y, 半径大小=8, 填充颜色=颜色.红色, 描边宽度=1.2, 描边颜色=颜色.白色)
                continue

            self.画圆(x=x, y=y, 半径=3, 填充颜色=颜色.白色, 描边宽度=0.8, 描边颜色=颜色.红色)
            self.画圆(x=x, y=y, 半径=1.8, 填充颜色=颜色.红色, 描边宽度=0)
            if 省会 not in ["北京", "天津", "上海", "重庆", ""]:
                省会文字 = self.写字(x=x + offset_x, y=y - 4 + offset_y, 文字=省会, 字体大小=font_size,
                               垂直基线对齐=文字垂直基线对齐.底线对齐)
                self.省会文字微调(省会文字, 省会坐标)

    def 获取区域颜色(self, 区域名称):
        if 区域名称 in self.区域颜色:
            return self.区域颜色[区域名称]

        if 区域名称 in self.默认区域颜色:
            return self.默认区域颜色[区域名称]

        return "none"

    def 区域路径设置(self, 序号, 区域名称):
        return {"填充颜色": self.获取区域颜色(区域名称)}

        # if 区域名称 in self.区域颜色:
        #     return {"填充颜色": self.区域颜色[区域名称]}
        #
        # if 区域名称 in self.默认区域颜色:
        #     return {"填充颜色": self.默认区域颜色[区域名称]}
        #
        # return {"填充颜色": "none"}

    def 区域名称设置(self, 区域名称):
        if 区域名称 in ["北京", "天津", "澳门", "香港", "上海"]:
            return {"字体大小": 6}
        if 区域名称 in ["宁夏", "重庆", "海南", "台湾"]:
            return {"字体大小": 8}
        return {"字体大小": 10}

    def 区域文字调整(self, 区域名称: str, 区域文字元素: 文字元素, 位置信息):
        # 区域文字元素.阴影(偏移=(0.4, 0.4), 模糊度=0.5)
        区域文字元素.阴影(偏移=(0.5, 0.5), 模糊度=0)
        if 区域名称 in self.文字调整:
            self.文字调整[区域名称](区域文字元素, 位置信息)
            if callable(self.区域文字微调):
                self.区域文字微调(区域名称, 区域文字元素, 位置信息, self.获取区域颜色(区域名称))

    def _区域名称设置(self, 区域名称):
        设置信息 = self.区域名称设置(区域名称)
        if "区域名称" not in 设置信息:
            设置信息["区域名称"] = 区域名称
        if "描边宽度" not in 设置信息:
            设置信息["描边宽度"] = 0.05
        if "描边颜色" not in 设置信息:
            设置信息["描边颜色"] = 颜色.黑色
        if "填充颜色" not in 设置信息:
            设置信息["填充颜色"] = 颜色.白色
        if "字体大小" not in 设置信息:
            设置信息["字体大小"] = 4
        return 设置信息

    def _区域线设置(self, 序号, 区域名称):
        连线样式 = self.区域路径设置(序号, 区域名称)
        if "描边颜色" not in 连线样式:
            连线样式["描边颜色"] = "#666666"
        if "描边宽度" not in 连线样式:
            连线样式["描边宽度"] = 1.5
        if "填充颜色" not in 连线样式:
            连线样式["填充颜色"] = "none"
        return 连线样式

    def _绘制区域线(self):
        区域文字信息列表 = []
        for i, 区域 in 索引列举(self.地图数据):
            点列表 = self.地图数据[区域]
            连线样式 = self._区域线设置(i, 区域)
            区域连线 = self.连线(点列表, 描边宽度=连线样式["描边宽度"], 描边颜色=连线样式["描边颜色"], 填充颜色=连线样式["填充颜色"])
            区域连线.描边线连接样式(描边线连接样式.圆角连接)
            # 区域连线.立体阴影(偏移=(0.5, 0.5), 阴影模糊度=0.5, 灯光颜色=颜色.白色, 灯光位置=(-50, -50, 200))
            位置信息 = 区域连线.获取位置信息()
            区域文字信息列表.append((区域, 位置信息))
        return 区域文字信息列表

    def _绘制区域名称(self, 区域文字信息列表):
        for 区域名称, 位置信息 in 区域文字信息列表:
            区域名称设置 = self._区域名称设置(区域名称)

            区域文字元素 = self.写字(x=位置信息.中心x, y=位置信息.中心y, 文字=区域名称设置["区域名称"],
                             描边颜色=区域名称设置["描边颜色"], 描边宽度=区域名称设置["描边宽度"],
                             字体大小=区域名称设置["字体大小"], 填充颜色=区域名称设置["填充颜色"])

            self.区域文字调整(区域名称, 区域文字元素, 位置信息)

    def 页面设置(self, 设置: 纸张设置):
        # 输出 PDF 文件，以及 页面打印，在这里设置好
        设置.上页边距 = "0.8cm"
        设置.下页边距 = 0
        设置.左页边距 = "1.4cm"
        # 设置.页面方向 = 纸张方向.横向
        设置.右页边距 = 0
        设置.页面缩放 = 1.25

    def 写说明文字(self):
        self.写网址信息(x=self.宽 / 2, y=90, 字体大小=12, 水平基线对齐=文字水平基线对齐.中点对齐)
        self.写软件信息(x=self.宽 / 2, y=120, 字体大小=28, 填充颜色=颜色.深灰色, 水平基线对齐=文字水平基线对齐.中点对齐)
        self.写字(x=self.宽 / 2, y=60, 文字="中国地图高清拼图", 填充颜色="#666666",
                字体=系统字体.隶书, 字体大小=30)#.阴影(偏移=(1, 1), 模糊度=1)

    def 创作(self):
        # self.显示网格(网格线距=20, 网格颜色=颜色.暗灰色, 网格透明度=1, 网格字体大小=9)
        # self.显示图框()
        self.绘制地图()
        self.写说明文字()
        # self.贴图(x=12, y=106, 图片文件=资源库目录("素材/中国地图.png"), 透明度=0.7).缩放(0.434)  # .旋转(5)
